From 3de05726eb9d6bd8637134eb37ce8072c4289cd6 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Sat, 19 Nov 2022 15:39:09 -0500 Subject: config: Custom profile detection fixes Also only reads/writes applicable configs for the custom profiles. --- src/yuzu/configuration/config.cpp | 89 ++++++++++++++-------- src/yuzu/configuration/config.h | 2 + .../configuration/configure_input_per_game.cpp | 61 +++++++++------ src/yuzu/configuration/configure_input_per_game.h | 17 +++-- src/yuzu/configuration/configure_per_game.cpp | 2 +- src/yuzu/main.cpp | 1 + 6 files changed, 108 insertions(+), 64 deletions(-) diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index 4067ea607..cc1ba9f70 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -124,6 +124,10 @@ void Config::Initialize(const std::string& config_name) { } } +bool Config::IsCustomConfig() { + return type == ConfigType::PerGameConfig; +} + /* {Read,Write}BasicSetting and WriteGlobalSetting templates must be defined here before their * usages later in this file. This allows explicit definition of some types that don't work * nicely with the general version. @@ -186,7 +190,7 @@ void Config::WriteGlobalSetting(const Settings::SwitchableSetting& void Config::ReadPlayerValue(std::size_t player_index) { const QString player_prefix = [this, player_index] { - if (type == ConfigType::InputProfile && global) { + if (type == ConfigType::InputProfile) { return QString{}; } else { return QStringLiteral("player_%1_").arg(player_index); @@ -194,8 +198,20 @@ void Config::ReadPlayerValue(std::size_t player_index) { }(); auto& player = Settings::values.players.GetValue()[player_index]; + if (IsCustomConfig()) { + const auto profile_name = + qt_config->value(QStringLiteral("%1profile_name").arg(player_prefix), QString{}) + .toString() + .toStdString(); + if (profile_name.empty()) { + // Use the global input config + player = Settings::values.players.GetValue(true)[player_index]; + return; + } + player.profile_name = profile_name; + } - if (player_prefix.isEmpty()) { + if (player_prefix.isEmpty() && Settings::IsConfiguringGlobal()) { const auto controller = static_cast( qt_config ->value(QStringLiteral("%1type").arg(player_prefix), @@ -244,14 +260,6 @@ void Config::ReadPlayerValue(std::size_t player_index) { ->value(QStringLiteral("%1button_color_right").arg(player_prefix), Settings::JOYCON_BUTTONS_NEON_RED) .toUInt(); - - // This only applies to per-game configs - if (!global) { - player.profile_name = - qt_config->value(QStringLiteral("%1profile_name").arg(player_prefix), QString{}) - .toString() - .toStdString(); - } } for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) { @@ -394,12 +402,28 @@ void Config::ReadAudioValues() { } void Config::ReadControlValues() { - Settings::values.players.SetGlobal(global); qt_config->beginGroup(QStringLiteral("Controls")); + Settings::values.players.SetGlobal(!IsCustomConfig()); for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) { ReadPlayerValue(p); } + ReadGlobalSetting(Settings::values.use_docked_mode); + + // Disable docked mode if handheld is selected + const auto controller_type = Settings::values.players.GetValue()[0].controller_type; + if (controller_type == Settings::ControllerType::Handheld) { + Settings::values.use_docked_mode.SetGlobal(!IsCustomConfig()); + Settings::values.use_docked_mode.SetValue(false); + } + + ReadGlobalSetting(Settings::values.vibration_enabled); + ReadGlobalSetting(Settings::values.enable_accurate_vibrations); + ReadGlobalSetting(Settings::values.motion_enabled); + if (IsCustomConfig()) { + qt_config->endGroup(); + return; + } ReadDebugValues(); ReadKeyboardValues(); ReadMouseValues(); @@ -421,18 +445,6 @@ void Config::ReadControlValues() { ReadBasicSetting(Settings::values.tas_loop); ReadBasicSetting(Settings::values.pause_tas_on_load); - ReadGlobalSetting(Settings::values.use_docked_mode); - - // Disable docked mode if handheld is selected - const auto controller_type = Settings::values.players.GetValue()[0].controller_type; - if (controller_type == Settings::ControllerType::Handheld) { - Settings::values.use_docked_mode.SetValue(false); - } - - ReadGlobalSetting(Settings::values.vibration_enabled); - ReadGlobalSetting(Settings::values.enable_accurate_vibrations); - ReadGlobalSetting(Settings::values.motion_enabled); - ReadBasicSetting(Settings::values.controller_navigation); qt_config->endGroup(); @@ -932,7 +944,7 @@ void Config::ReadValues() { void Config::SavePlayerValue(std::size_t player_index) { const QString player_prefix = [this, player_index] { - if (type == ConfigType::InputProfile && global) { + if (type == ConfigType::InputProfile) { return QString{}; } else { return QStringLiteral("player_%1_").arg(player_index); @@ -940,12 +952,20 @@ void Config::SavePlayerValue(std::size_t player_index) { }(); const auto& player = Settings::values.players.GetValue()[player_index]; + if (IsCustomConfig()) { + if (player.profile_name.empty()) { + // No custom profile selected + return; + } + WriteSetting(QStringLiteral("%1profile_name").arg(player_prefix), + QString::fromStdString(player.profile_name), QString{}); + } WriteSetting(QStringLiteral("%1type").arg(player_prefix), static_cast(player.controller_type), static_cast(Settings::ControllerType::ProController)); - if (!player_prefix.isEmpty()) { + if (!player_prefix.isEmpty() || !Settings::IsConfiguringGlobal()) { WriteSetting(QStringLiteral("%1connected").arg(player_prefix), player.connected, player_index == 0); WriteSetting(QStringLiteral("%1vibration_enabled").arg(player_prefix), @@ -960,12 +980,6 @@ void Config::SavePlayerValue(std::size_t player_index) { player.button_color_left, Settings::JOYCON_BUTTONS_NEON_BLUE); WriteSetting(QStringLiteral("%1button_color_right").arg(player_prefix), player.button_color_right, Settings::JOYCON_BUTTONS_NEON_RED); - - // This only applies to per-game configs - if (!global) { - WriteSetting(QStringLiteral("%1profile_name").arg(player_prefix), - QString::fromStdString(player.profile_name), QString{}); - } } for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) { @@ -1100,12 +1114,16 @@ void Config::SaveAudioValues() { } void Config::SaveControlValues() { - Settings::values.players.SetGlobal(global); qt_config->beginGroup(QStringLiteral("Controls")); + Settings::values.players.SetGlobal(!IsCustomConfig()); for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) { SavePlayerValue(p); } + if (IsCustomConfig()) { + qt_config->endGroup(); + return; + } SaveDebugValues(); SaveMouseValues(); SaveTouchscreenValues(); @@ -1590,6 +1608,13 @@ void Config::SaveControlPlayerValue(std::size_t player_index) { qt_config->endGroup(); } +void Config::ClearControlPlayerValues() { + qt_config->beginGroup(QStringLiteral("Controls")); + // If key is an empty string, all keys in the current group() are removed. + qt_config->remove(QString{}); + qt_config->endGroup(); +} + const std::string& Config::GetConfigFilePath() const { return qt_config_loc; } diff --git a/src/yuzu/configuration/config.h b/src/yuzu/configuration/config.h index 06fa7d2d0..7d26e9ab6 100644 --- a/src/yuzu/configuration/config.h +++ b/src/yuzu/configuration/config.h @@ -34,6 +34,7 @@ public: void ReadControlPlayerValue(std::size_t player_index); void SaveControlPlayerValue(std::size_t player_index); + void ClearControlPlayerValues(); const std::string& GetConfigFilePath() const; @@ -58,6 +59,7 @@ public: private: void Initialize(const std::string& config_name); + bool IsCustomConfig(); void ReadValues(); void ReadPlayerValue(std::size_t player_index); diff --git a/src/yuzu/configuration/configure_input_per_game.cpp b/src/yuzu/configuration/configure_input_per_game.cpp index af5cee542..78e65d468 100644 --- a/src/yuzu/configuration/configure_input_per_game.cpp +++ b/src/yuzu/configuration/configure_input_per_game.cpp @@ -6,12 +6,14 @@ #include "core/hid/emulated_controller.h" #include "core/hid/hid_core.h" #include "ui_configure_input_per_game.h" +#include "yuzu/configuration/config.h" #include "yuzu/configuration/configure_input_per_game.h" #include "yuzu/configuration/input_profiles.h" -ConfigureInputPerGame::ConfigureInputPerGame(Core::System& system_, QWidget* parent) +ConfigureInputPerGame::ConfigureInputPerGame(Core::System& system_, Config* config_, + QWidget* parent) : QWidget(parent), ui(std::make_unique()), - profiles(std::make_unique()), system{system_} { + profiles(std::make_unique()), system{system_}, config{config_} { ui->setupUi(this); const std::array labels = { ui->label_player_1, ui->label_player_2, ui->label_player_3, ui->label_player_4, @@ -22,6 +24,8 @@ ConfigureInputPerGame::ConfigureInputPerGame(Core::System& system_, QWidget* par ui->profile_player_5, ui->profile_player_6, ui->profile_player_7, ui->profile_player_8, }; + Settings::values.players.SetGlobal(false); + const auto& profile_names = profiles->GetInputProfileNames(); const auto populate_profiles = [this, &profile_names](size_t player_index) { const auto previous_profile = @@ -29,6 +33,7 @@ ConfigureInputPerGame::ConfigureInputPerGame(Core::System& system_, QWidget* par auto* const player_combobox = profile_comboboxes[player_index]; player_combobox->addItem(tr("Use global input configuration")); + for (size_t index = 0; index < profile_names.size(); ++index) { const auto& profile_name = profile_names[index]; player_combobox->addItem(QString::fromStdString(profile_name)); @@ -38,7 +43,6 @@ ConfigureInputPerGame::ConfigureInputPerGame(Core::System& system_, QWidget* par } } }; - for (size_t index = 0; index < profile_comboboxes.size(); ++index) { labels[index]->setText(tr("Player %1 profile").arg(index + 1)); populate_profiles(index); @@ -53,8 +57,10 @@ void ConfigureInputPerGame::ApplyConfiguration() { } void ConfigureInputPerGame::LoadConfiguration() { + static constexpr size_t HANDHELD_INDEX = 8; + auto& hid_core = system.HIDCore(); - const auto load_player_profile = [this, &hid_core](size_t player_index) { + for (size_t player_index = 0; player_index < profile_comboboxes.size(); ++player_index) { Settings::values.players.SetGlobal(false); auto* emulated_controller = hid_core.GetEmulatedControllerByIndex(player_index); @@ -63,40 +69,47 @@ void ConfigureInputPerGame::LoadConfiguration() { const auto selection_index = player_combobox->currentIndex(); if (selection_index == 0) { Settings::values.players.GetValue()[player_index].profile_name = ""; + if (player_index == 0) { + Settings::values.players.GetValue()[HANDHELD_INDEX] = {}; + } Settings::values.players.SetGlobal(true); emulated_controller->ReloadFromSettings(); - return; + continue; } const auto profile_name = player_combobox->itemText(selection_index).toStdString(); if (profile_name.empty()) { - return; + continue; } + auto& player = Settings::values.players.GetValue()[player_index]; + player.profile_name = profile_name; + // Read from the profile into the custom player settings profiles->LoadProfile(profile_name, player_index); - Settings::values.players.GetValue()[player_index].profile_name = profile_name; + // Make sure the controller is connected + player.connected = true; + emulated_controller->ReloadFromSettings(); - }; - for (size_t index = 0; index < profile_comboboxes.size(); ++index) { - load_player_profile(index); + if (player_index > 0) { + continue; + } + // Handle Handheld cases + auto& handheld_player = Settings::values.players.GetValue()[HANDHELD_INDEX]; + auto* handheld_controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Handheld); + if (player.controller_type == Settings::ControllerType::Handheld) { + handheld_player = player; + } else { + handheld_player = {}; + } + handheld_controller->ReloadFromSettings(); } } void ConfigureInputPerGame::SaveConfiguration() { Settings::values.players.SetGlobal(false); - auto& hid_core = system.HIDCore(); - const auto save_player_profile = [this, &hid_core](size_t player_index) { - const auto selection_index = profile_comboboxes[player_index]->currentIndex(); - if (selection_index == 0) { - return; - } - auto* emulated_controller = hid_core.GetEmulatedControllerByIndex(player_index); - profiles->SaveProfile(Settings::values.players.GetValue()[player_index].profile_name, - player_index); - emulated_controller->ReloadFromSettings(); - }; - - for (size_t index = 0; index < profile_comboboxes.size(); ++index) { - save_player_profile(index); + // Clear all controls from the config in case the user reverted back to globals + config->ClearControlPlayerValues(); + for (size_t index = 0; index < Settings::values.players.GetValue().size(); ++index) { + config->SaveControlPlayerValue(index); } } diff --git a/src/yuzu/configuration/configure_input_per_game.h b/src/yuzu/configuration/configure_input_per_game.h index a586ec07c..660faf574 100644 --- a/src/yuzu/configuration/configure_input_per_game.h +++ b/src/yuzu/configuration/configure_input_per_game.h @@ -7,21 +7,23 @@ #include +#include "ui_configure_input_per_game.h" +#include "yuzu/configuration/input_profiles.h" + +class QComboBox; + namespace Core { class System; -} - -namespace Ui { -class ConfigureInputPerGame; -} +} // namespace Core -class InputProfiles; +class Config; class ConfigureInputPerGame : public QWidget { Q_OBJECT public: - explicit ConfigureInputPerGame(Core::System& system_, QWidget* parent = nullptr); + explicit ConfigureInputPerGame(Core::System& system_, Config* config_, + QWidget* parent = nullptr); /// Load and Save configurations to settings file. void ApplyConfiguration(); @@ -39,4 +41,5 @@ private: std::array profile_comboboxes; Core::System& system; + Config* config; }; diff --git a/src/yuzu/configuration/configure_per_game.cpp b/src/yuzu/configuration/configure_per_game.cpp index cf0a6dc0e..93db47cfd 100644 --- a/src/yuzu/configuration/configure_per_game.cpp +++ b/src/yuzu/configuration/configure_per_game.cpp @@ -50,7 +50,7 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::st general_tab = std::make_unique(system_, this); graphics_tab = std::make_unique(system_, this); graphics_advanced_tab = std::make_unique(system_, this); - input_tab = std::make_unique(system_, this); + input_tab = std::make_unique(system_, game_config.get(), this); system_tab = std::make_unique(system_, this); ui->setupUi(this); diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index e0c353788..21983a799 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -1669,6 +1669,7 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t ? Common::FS::PathToUTF8String(file_path.filename()) : fmt::format("{:016X}", title_id); Config per_game_config(config_file_name, Config::ConfigType::PerGameConfig); + system->HIDCore().ReloadInputDevices(); system->ApplySettings(); } -- cgit v1.2.3